package com.example.activity;


import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;

import com.example.adapter.ChatMessageAdapter;
import com.example.adapter.QuestionAdapter;
import com.example.bean.ChatMessage;
import com.example.bean.QuestionBean;
import com.example.dialog.NoticeDialog;
import com.example.myrobot.R;
import com.example.utils.HttpUtils;
import com.example.utils.JsonParser;
import com.example.utils.ToastUtil;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.ui.RecognizerDialogListener;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import okhttp3.Call;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {
    private static final int TYPE_TEXT = 1;
    private static final int TYPE_VOICE = 2;

    private ImageView ivSwitch;
    private Button btnVoice;
    private Button btnSendRequest;
    private EditText etMsgInput;
    private ListView lvChatMessage;
    private ListView lvQuestion;
    private ViewGroup flQuestion;
    private ChatMessageAdapter adapter;
    private List<ChatMessage> data;
    private long mExitTime = 0;
    private int type = TYPE_TEXT;
    private List<QuestionBean> questionBeans = new ArrayList<>();

    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            ChatMessage message = (ChatMessage) msg.obj;
            data.add(message);
            adapter.notifyDataSetChanged();
            lvChatMessage.setSelection(adapter.getCount() - 1);
            return false;
        }
    });


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initToolBar();
        initData();
        initView();
        initEvent();

        //初始化讯飞语音
        SpeechManager.getInstance().init(getApplicationContext());
        //加载问题数据
        loadQuestionData();
        //延时弹出公告
        ivSwitch.postDelayed(new Runnable() {
            @Override
            public void run() {
                new NoticeDialog(MainActivity.this).show();
            }
        }, 800);
    }

    private void initToolBar() {
        Toolbar toolbar = findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(false);
        }
    }

    private void initData() {
        data = new ArrayList<>();
        data.add(new ChatMessage("很高兴为您服务，主人", new Date(), ChatMessage.Type.INCOMING));
        long lastTime = System.currentTimeMillis();
    }

    private void initView() {
        ivSwitch = findViewById(R.id.iv_switch);
        btnVoice = findViewById(R.id.btn_voice);
        btnSendRequest = findViewById(R.id.btn_send_request);
        etMsgInput = findViewById(R.id.et_message_content);
        View tvtotime = findViewById(R.id.tv_to_time);
        View tvfromtime = findViewById(R.id.tv_from_time);
        lvChatMessage = findViewById(R.id.list_chat_msg);
        lvQuestion = findViewById(R.id.lv_question);
        flQuestion = findViewById(R.id.fl_question);
        adapter = new ChatMessageAdapter(this, data);
        lvChatMessage.setAdapter(adapter);

        initBottomView();
    }

    private void initBottomView() {
        if (type == TYPE_TEXT) {
            //显示发送文本view
            ivSwitch.setImageResource(R.mipmap.chat_keyboard_normal);
            etMsgInput.setVisibility(View.VISIBLE);
            btnSendRequest.setVisibility(View.VISIBLE);
            btnVoice.setVisibility(View.GONE);
        } else {
            //显示发送语音view
            ivSwitch.setImageResource(R.mipmap.chat_voice_normal);
            etMsgInput.setVisibility(View.GONE);
            btnSendRequest.setVisibility(View.GONE);
            btnVoice.setVisibility(View.VISIBLE);
        }
    }

    private void initEvent() {
        ivSwitch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (type == TYPE_TEXT) {
                    type = TYPE_VOICE;
                } else {
                    type = TYPE_TEXT;
                }
                initBottomView();
            }
        });

        btnVoice.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                checkRecordPermission();
            }
        });

        /**
         * 当点击发送按钮时
         * 首先获取用户输入的信息，调用adapter.notifyDataSetChanged();方法将其显示到listview中
         * 再调用我们封装的sendOkHttpRequest()方法从接口请求返回的数据
         * 注意此时实现需要okhttp3.Callback接口中的onFailure()和onResponse()方法，分别表示请求失败和请求成功的情况
         * onFailure()和onResponse()方法中依然处于子线程中，如果需要更新界面需要调用runOnUiThread()方法
         * 或使用handler,我们这里选择使用handler
         */
        btnSendRequest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String message = etMsgInput.getText().toString().trim();
                if (TextUtils.isEmpty(message)) {
                    ToastUtil.show(getApplicationContext(), "请输入问题");
                    return;
                }
                ChatMessage toMessage = new ChatMessage(message, new Date(), ChatMessage.Type.OUTCOMING);
                data.add(toMessage);
//                nowTime = System.currentTimeMillis();
//                if(nowTime - lastTime > 5 * 1000) {
//                    tvToTime.setVisibility(View.VISIBLE);
//                } else {
//                    tvToTime.setVisibility(View.GONE);
//                }
//                lastTime = nowTime;
                adapter.notifyDataSetChanged();
                lvChatMessage.setSelection(adapter.getCount() - 1);
                etMsgInput.setText("");
                requestRobot(message);
            }
        });

        etMsgInput.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                String content = etMsgInput.getText().toString().trim();
                if (TextUtils.isEmpty(content)) {
                    btnSendRequest.setBackgroundResource(R.drawable.btn_sended);
                } else {
                    btnSendRequest.setBackgroundResource(R.drawable.btn_sending);
                }
            }

            @Override
            public void afterTextChanged(Editable s) {
                String content = etMsgInput.getText().toString().trim();
                if (TextUtils.isEmpty(content)) {
                    flQuestion.setVisibility(View.GONE);
                    return;
                }
                //匹配问题列表
                final List<QuestionBean> questions = new ArrayList<>();
                for (QuestionBean bean : questionBeans) {
                    if (bean.getQuestion().contains(content)) {
                        questions.add(bean);
                    }
                }
                if (!questions.isEmpty()) {
                    //弹出问题列表
                    flQuestion.setVisibility(View.VISIBLE);
                    lvQuestion.setAdapter(new QuestionAdapter(MainActivity.this, questions));
                    lvQuestion.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                        @Override
                        public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                            //发送问题
                            QuestionBean bean = questions.get(position);
                            ChatMessage toMessage = new ChatMessage(bean.getQuestion(), new Date(), ChatMessage.Type.OUTCOMING);
                            ChatMessage fromMessage = new ChatMessage(bean.getAnswer(), new Date(), ChatMessage.Type.INCOMING);
                            data.add(toMessage);
                            data.add(fromMessage);

                            adapter.notifyDataSetChanged();
                            lvChatMessage.setSelection(adapter.getCount() - 1);
                            etMsgInput.setText("");

                            flQuestion.setVisibility(View.GONE);
                        }
                    });
                } else {
                    flQuestion.setVisibility(View.GONE);
                }
            }
        });

        lvChatMessage.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                flQuestion.setVisibility(View.GONE);
                return true;
            }
        });
        flQuestion.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                flQuestion.setVisibility(View.GONE);
                return true;
            }
        });
        findViewById(R.id.iv_notice).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new NoticeDialog(view.getContext()).show();
            }
        });
    }

    /**
     * 请求机器人
     */
    private void requestRobot(String message) {
        HttpUtils.sendOkHttpRequest(message, new okhttp3.Callback() {

            @Override
            public void onFailure(Call call, IOException e) {//请求过程中出现错误的回调
                e.printStackTrace();
                ToastUtil.show(getApplicationContext(), "请求过程中出错了");
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {//请求成功的回调
                final String strResponse = JsonParser.parJson(response.body().string());//从返回的Json数据中解析出有用的数据
                ChatMessage fromMessage = new ChatMessage(strResponse, new Date(), ChatMessage.Type.INCOMING);
                Message message2 = new Message();
                message2.obj = fromMessage;
                handler.sendMessage(message2);
            }
        });
    }

    private void showVoiceDialog() {
        SpeechManager.getInstance().showSpeechDialog(MainActivity.this, new RecognizerDialogListener() {
            @Override
            public void onResult(RecognizerResult results, boolean b) {
                try {
                    JSONObject resultJson = new JSONObject(results.getResultString());
                    int sn = resultJson.optInt("sn");
                    if (sn != 1) {
                        ToastUtil.show(getApplicationContext(), "语音识别失败");
                        return;
                    }

                    String message = "";
                    JSONArray wsArray = resultJson.getJSONArray("ws");
                    for (int i = 0; i < wsArray.length(); i++) {
                        JSONObject wsObj = new JSONObject(wsArray.get(i).toString());
                        JSONArray cwArray = wsObj.getJSONArray("cw");

                        for (int j = 0; j < cwArray.length(); j++) {
                            JSONObject cwObj = new JSONObject(cwArray.get(j).toString());
                            message = message + cwObj.get("w");
                        }
                    }

                    ChatMessage toMessage = new ChatMessage(message, new Date(), ChatMessage.Type.OUTCOMING);
                    data.add(toMessage);
                    adapter.notifyDataSetChanged();
                    lvChatMessage.setSelection(adapter.getCount() - 1);

                    requestRobot(message);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onError(SpeechError speechError) {
                ToastUtil.show(getApplicationContext(), "语音识别失败:" + speechError.getErrorDescription());
            }
        });
    }

    private void checkRecordPermission() {
        int result = ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.RECORD_AUDIO);
        if (result == PackageManager.PERMISSION_DENIED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 0);
        } else {
            showVoiceDialog();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 0) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                showVoiceDialog();
            } else {
                ToastUtil.show(getApplicationContext(), "权限未同意,功能无法使用");
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    public void onBackPressed() {
        // 退出程序
        long startTime = System.currentTimeMillis();
        if ((startTime - mExitTime) < 3000) {
            super.onBackPressed();
        } else {
            // 如果两次按键时间间隔大于3000毫秒，则不退出
            ToastUtil.show(getApplicationContext(), "再按一次退出");
            // 更新mExitTime
            mExitTime = System.currentTimeMillis();
        }
    }

    @SuppressLint("StaticFieldLeak")
    private void loadQuestionData() {
        final String url = "https://gitee.com/duanfb/SpeechRobot/raw/master/data/question.json";
        new AsyncTask<Void, Void, String>() {

            @Override
            protected String doInBackground(Void... voids) {
                try {
                    Document doc = Jsoup.connect(url).ignoreContentType(true).get();
                    return doc.body().text();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return "";
            }

            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);
                if (!isFinishing()) {
                    try {
                        questionBeans = JsonParser.toList(result, QuestionBean.class);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (questionBeans == null) {
                        questionBeans = Collections.emptyList();
                    }
                }
            }
        }.execute();
    }
}